package com.summer.safe.config.shiro;

import com.summer.safe.utils.*;
import com.summer.safe.base.Principal;
import com.summer.safe.system.entity.Menu;
import com.summer.safe.system.entity.Role;
import com.summer.safe.system.entity.User;
import com.summer.safe.system.service.SystemService;
import com.summer.safe.utils.*;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * 自定义的realm
 */
public class RealmConfig extends AuthorizingRealm {

    private Logger logger = LoggerFactory.getLogger(getClass());

    private SystemService systemService;



    /**
     * 获取系统业务对象
     */
    public SystemService getSystemService() {
        if (systemService == null) {
            systemService = SpringContextUtil.getBean(SystemService.class);
        }
        return systemService;
    }


    /**
     *  定义如何获取用户的角色和权限的逻辑，给shiro做权限判断
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {// 登录后的每次操作都会执行(当然不包括游客,匿名访问)
        /**
         * 获取session中的用户
         */
        Principal principal = (Principal) principals.fromRealm(this.getClass().getName()).iterator().next();
        User user = getSystemService().getByLoginName(principal.getLoginName());
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        /**
         * 将权限放入shiro中.
         */
        List<Menu> menus = UserUtils.getMenuList();
        menus.forEach(menu -> {
            if (!StringUtils.isEmpty(menu.getPermission())) {
                // 添加基于Permission的权限信息
                for (String permission : StringUtils.split(menu.getPermission(), ",")) {
                    info.addStringPermission(permission);
                }
            }
        });
        // 添加用户角色信息
        List<Role> roles = user.getRoleList();
        roles.forEach(role -> info.addRole(role.getName()));

        logger.info("用户" + user.getLoginName() + "权限放入完成!");
        // 记录登录日志
        LogUtils.saveLog(HttpKit.getRequest(), "系统登录");
        return info;
    }

    /**
     * 定义如何获取用户信息的业务逻辑，给shiro做登录
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        String username = upToken.getUsername();
        User user=getSystemService().getByLoginName(username);
        Session session = UserUtils.getSession();

        if (user != null) {
            /**
             * 放入shiro.调用CredentialsMatcher检验密码
             */
            byte[] salt = Encodes.decodeHex(user.getPassword().substring(0, 16));
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(new Principal(user), user.getPassword(),ByteSource.Util.bytes(salt),  this.getClass().getName());
            session.setAttribute(SessionUtils.SKEY_USER_ID, user.getId());
            return info;
        }else{
            return null;
        }
    }
    /**
     * 清理缓存权限
     */
    public void clearCachedAuthorizationInfo(){
        this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
    }






}
